package io.renren.modules.wcs.controller;

import com.ioserver.bean.Union_DataType;
import io.renren.common.utils.R;
import io.renren.datasource.annotation.DataSource;

import io.renren.modules.ioserver.IOServerService;
import io.renren.modules.wcs.entity.*;
import io.renren.modules.wcs.enums.IOServerEnum;
import io.renren.modules.wcs.listenSlaveDB.controller.MySqlBean;
import io.renren.modules.wcs.listenSlaveDB.controller.TestBean;
import io.renren.modules.wcs.listenSlaveDB.dao.TestDaos;
import io.renren.modules.wcs.service.DDJService;
import io.renren.modules.wcs.listenSlaveDB.SalveThread;
import io.renren.modules.wcs.listenSlaveDB.entity.TestEntity2;
import io.renren.modules.wcs.listenSlaveDB.service.TestService;
import io.renren.modules.wcs.listenSlaveDB.entity.ThreadFlag;
import io.renren.modules.wcs.service.WeighingPLCService;
import io.renren.modules.websocket.MessageModule;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;
import java.util.Random;


/**
 * @Author: 蔡翔
 * @Date: 2019/10/12 15:15
 * @Version 1.0
 */
@RestController
@Api(description = "wmc测试接口")
@RequestMapping("/wmcTest")
@DependsOn("springContextUtils")
public class WmcController {

    private static final Logger logger = LoggerFactory.getLogger(WmcController.class);


    @Autowired
    DDJService ddjService;

    @Autowired
    WeighingPLCService weighingPLCService;


    @Autowired
    private TestService testService;

    @Autowired
    private IOServerService ioServerService;

    @Autowired
    private MessageModule messageModule;


    private static SalveThread t = new SalveThread();

    @Autowired
    TestBean testBean;

    @Autowired
    MySqlBean mysqlBean;

    @ApiOperation(value = "modifyPCStatus", notes = "modifyPCStatus")
    @PostMapping("/modifyPCStatus")
    public R modifyPCStatus() throws Exception {
        Integer i = ioServerService.setTagValue(IOServerEnum.PC_Status.getCollectionPointName(), "88", 1);
        return R.ok().put("result",i);
    }
    // 测试（数据类型） 和plc通讯
    /**
     * 测试real 类型（get / set）
     **/
    @ApiOperation(value = "testReal", notes = "testReal")
    @PostMapping("/testReal")
    public R testReal() throws Exception {
        Integer integer = ioServerService.setTagValue(IOServerEnum.Take_Position.getCollectionPointName(), "55", 2);
        Thread.sleep(1000);
        Union_DataType.ByValue valueByName = ioServerService.getValueByName(IOServerEnum.Take_Position.getCollectionPointName());
        return R.ok().put("Take_Position",valueByName);
    }

    @ApiOperation(value = "testTestDao", notes = "testTestDao")
    @PostMapping("/testTestDao")
    public R testTestDao() throws Exception {

        return R.ok().put("count:",mysqlBean.selectAll());
    }
    /**
     * 测试boolen 类型（get / set）
     **/
    @ApiOperation(value = "testBoolen", notes = "testBoolen")
    @PostMapping("/testBoolen")
    public R testBoolen() throws Exception {
        Integer integer = ioServerService.setTagValue(IOServerEnum.L_Start.getCollectionPointName(), "1", 4);
        Thread.sleep(1000);
        Union_DataType.ByValue valueByName = ioServerService.getValueByName(IOServerEnum.L_Start.getCollectionPointName());
        return R.ok().put("L_Start",valueByName);
    }
    /**
     * 测试Byte 类型（get / set）
     **/
    @ApiOperation(value = "testByte", notes = "testByte")
    @PostMapping("/testByte")
    public R testByte() throws Exception {
        Integer integer = ioServerService.setTagValue(IOServerEnum.Device_Status.getCollectionPointName(), "88", 5);
        Thread.sleep(1000);
        Union_DataType.ByValue valueByName = ioServerService.getValueByName(IOServerEnum.Device_Status.getCollectionPointName());
        return R.ok().put("Device_Status",valueByName);
    }



    /**
     * 往sql-server 里面插入数据
     **/
    /*@ApiOperation(value = "insert-slave源", notes = "insert-slave源")
    @PostMapping("/insertSlave")
    @DataSource("slave1")
    public R insertSlave(@RequestBody ThreadFlag threadFlag){
        int min = 1;
        int max = 1000;
        int intBounded = min + ((int) (new Random().nextFloat() * (max - min)));
        Integer a = threadFlag.getFlagAS();
        String aa = a.toString();

        TestEntity2 testEntity = new TestEntity2();
        testEntity.setUserNames(aa);
        testEntity.setPassword("123");
        testEntity.setId(intBounded);

        if(testService.save(testEntity)){
            return R.ok("插入成功");
        }else {
            return R.error("插入失败");
        }
    }*/

    /**
     *  监听sql-server 并且把数据 移植到mysql
     **/
    @ApiOperation(value = "监听slave数据源", notes = "监听slave数据源")
    @PostMapping("/listenSlaveDB")
    @DataSource("slave1")
    public R listenSlaveDB(@RequestBody ThreadFlag flag){
        //注意***
        //@DependsOn("springContextUtils")
        //Controller层必须加@DependsOn() 否则项目打包成jar包会报错空指针异常
        // 一个接口 就是一个nio 线程。不同时间段 调用相同接口，都是不同的线程在跑。
        Integer flages = flag.getFlagAS();
        System.err.println("当前nio线程："+Thread.currentThread().getName());

        if(flages == 1){
            t.setName("listenSlaveDB-Thread");
            if(!t.isAlive()){
                t.start();
            }
            return R.ok("线程已近 启动");
        }
        if(flages ==3){
            t.wakeup();
            return R.ok("线程已被唤醒");
        }else{
            //t.interrupt();
            t.shutdown();
            return R.error("线程已近关闭");
        }
    }

    //websocket 对 一个点
    @ApiOperation(value = "testWebsocketToOne", notes = "testWebsocketToOne")
    @GetMapping("/websockettest/{userId}/{msg}")
    public R testWebsocketToOne(@PathVariable("userId") String userId, @PathVariable("msg") String msg) {
        if(messageModule.sendMessageToSomeone(msg,userId)){
            return R.ok().put("status","success");
        }else {
            return R.error("发送失败");
        }
    }

    //websocket 对 所有人
    @ApiOperation(value = "testWebsocketToAll", notes = "testWebsocketToAll")
    @GetMapping("/websockettest/{msg}")
    public R testWebsocketToAll(@PathVariable("msg") String msg) throws IOException {
        if(messageModule.sendMessageToAll(msg)){
            return R.ok().put("status","success");
        }else {
            return R.error("发送失败");
        }
    }

    /**
     * caixiang
     * 给plc 堆垛机 修改(current )变量值
     **/
    @ApiOperation(value = "modifyQiDian", notes = "modifyQiDian")
    @PostMapping("/modifyQiDian")
    public R modifyQiDian(@RequestBody DDJTaskEntity taksArgEntity) throws Exception {
        return R.ok().put("result",ioServerService.setTagValue("Take_Position","1001",2));
    }

    /**
     * caixiang
     *
     * 输入值：
     *      targetPosition  代表 起点
     *      takePosition    代表 终点
     *      type            代表 1《==》入库；；2 《==》 出库
     *      position        代表 某个口子
     *
     * 返回值:
     *      -1 代表 IOServer 写入异常
     *      -2 代表 堆垛机在执行任务途中 出现故障。
     *      1 代表 堆垛机执行成功
     *      2 代表 重置任务失败。
     *      3 代表 分发任务失败
     *
     *  给堆垛机下发任务并且监听
     *
     * status : work
     **/
    @ApiOperation(value = "sendTaskAndListening", notes = "sendTaskAndListening")
    @PostMapping("/sendTaskAndListening")
    public R sendTaskAndListening(@RequestBody DDJJobEntity ddjJobEntity) throws Exception {
        System.out.println(ddjService.getClass().toString()+"  "+ddjService.hashCode());
        Integer integer = ddjService.sendTaskAndListening(ddjJobEntity);
        return R.ok().put("result",integer);
    }




    @ApiOperation(value = "testLoggerErr", notes = "testLoggerErr")
    @PostMapping("/testLoggerErr")
    public R testLoggerErr() throws Exception {
        logger.error("测试错误");
        return R.ok();
    }

    @ApiOperation(value = "shutdownCurrentTask", notes = "shutdownCurrentTask")
    @PostMapping("/shutdownCurrentTask")
    public R shutdownCurrentTask() throws Exception {
        Integer integer = ddjService.stopCurrentTask();
        return R.ok().put("result",integer);
    }

    /**
     * 给称重plc 下达称重 指令（第一步）
     * Arg
     *          type  1 代表入库 ；； 2 代表出库
     * return
     *          -1  代表 IOServer 写入异常
     *          -2  代表 IOServer 写入失败
     *          0   代表写入 成功
     *
     * status ：work
     **/
    @ApiOperation(value = "warehousingBegin", notes = "warehousingBegin")
    @PostMapping("/warehousingBegin")
    public R warehousingBegin(@RequestBody WeightingEntity weightingEntity) throws Exception {
        Integer integer = weighingPLCService.warehousingBegin(weightingEntity.getType(),weightingEntity.getPosition());
        return R.ok().put("result",integer);
    }

    /**
     *  给称重plc 发送 指令后 去 取值（第二步）
     * */
    @ApiOperation(value = "getCargoAllMessage", notes = "getCargoAllMessage")
    @PostMapping("/getCargoAllMessage")
    public R getCargoAllMessage(@RequestBody CargoArg cargoArg) throws Exception {
        WeightingPLCEntity cargoAllMessage = weighingPLCService.getCargoAllMessage(Integer.parseInt(cargoArg.getCargoWeight().toString()),Integer.parseInt(cargoArg.getCargoHeight().toString()));
        return R.ok().put("result",cargoAllMessage);
    }





    //测试Short 类型
    @ApiOperation(value = "setCargoArg", notes = "setCargoArg")
    @PostMapping("/setCargoArg")
    public R setCargoArg(@RequestBody CargoArg cargoArg) throws Exception {
        return R.ok().put("result",ddjService.modifyCargoArg(cargoArg));
    }

    //测试Byte 类型
    @ApiOperation(value = "setDeviceStatus", notes = "setDeviceStatus")
    @PostMapping("/setDeviceStatus")
    public R setDeviceStatus(@RequestBody CargoArg cargoArg) throws Exception {
        return R.ok().put("result",ddjService.modifyDeviceStatus(cargoArg));
    }

    //测试Boolen 类型
    @ApiOperation(value = "setLStart", notes = "setLStart")
    @PostMapping("/setLStart")
    public R setLStart(@RequestBody CargoArg cargoArg) throws Exception {
        return R.ok().put("result",ddjService.modifyDeviceLstart(cargoArg));
    }

    //测试Word 类型  Word 统一用Short 类型，Short 16位的。Word 是两个字节（16位的）
    @ApiOperation(value = "setFirstHeight", notes = "setFirstHeight")
    @PostMapping("/setFirstHeight")
    public R setAndGetFirstHeight(@RequestBody CargoArg cargoArg) throws Exception {
        ddjService.modifyCargoFirstHeight(cargoArg);
        Thread.sleep(1000);
        Union_DataType.ByValue frist_height = ioServerService.getValueByName("Frist_Height");
        return R.ok().put("result",frist_height);
    }

    //测试Word 类型  Word 统一用Short 类型，Short 16位的。Word 是两个字节（16位的）
    @ApiOperation(value = "pushSensorAlarmMessage", notes = "pushSensorAlarmMessage")
    @PostMapping("/pushSensorAlarmMessage")
    public R pushSensorAlarmMessage(@RequestBody CargoArg cargoArg) throws Exception {
        int i = Integer.parseInt(cargoArg.getCargoWeight().toString());
        List<Character> characters = weighingPLCService.getSensorAlarmMessage(i);
        return R.ok().put("result",characters);
    }

}
